package com.generic.demo4;

import java.util.Arrays;

/**
 * @ClassName MyArrayList
 * @Description 模拟JDK的ArrayList的实现
 * @Author Kx
 * @Date 2025/3/26 16:21
 * @Version 1.0
 */
public class MyArrayList<T> {
    // 默认容量
    private static final int DEFAULT_CAPACITY = 10;

    // 存储数据的数组
    private Object[] data;

    // 存储数据的大小
    private int size;

    public MyArrayList() {
        // 初始化数组和size
        data = new Object[DEFAULT_CAPACITY];
        size = 0;
    }

    public MyArrayList(int capacity) {
        // 判断容量是否小于0
        if (capacity < 0){
            throw new RuntimeException("索引越界...");
        }
        // 初始化数组
        data = new Object[capacity];
    }

    /***
     * @author: kx
     * @date: 2025/3/26 16:35
     * @param value 需要添加的数据
     * @description: 把数据添加到数组中
    */
    public void add(T value){
        // 判断数据是否为空
        if (value == null){
            throw new NullPointerException("数据不能为空...");
        }
        // 判断数组是否满了
        if (size == data.length) {
            // 把原数组的数据拷贝到新数组中
            data = Arrays.copyOf(data,data.length * 2);
        }
        // 把数据添加到数组中
        data[size] = value;
        size++;
    }

    /***
     * @author: kx
     * @date: 2025/3/26 19:09
     * @param index 需要删除的数据的下标
     * @description: 删除数组中的数据
    */
    public void remove(int index){
        // 判断下标是否越界
        isIndexValid(index);

        // 循环把数组中下标大于index的数据往前移动一位
        System.arraycopy(data,index + 1,data,index,size - index - 1);

//        数组扩容：System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
//        Object src : 源数组
//        int srcPos : 从源数组的起始位置开始
//        Object dest : 目标数组
//        int destPos : 目标数组的开始起始位置
//        int length  : 要copy的数组的长度

        // 把最后一个数据设置为null
        data[--size] = null;
    }

    /***
     * @author: kx
     * @date: 2025/3/26 19:38
     * @return int : 数组的大小
     * @description: 返回集合的大小
    */
    public int size(){
        return size;
    }

    /***
     * @author: kx
     * @date: 2025/3/26 19:40
     * @param index : 指定下标
     * @return T : 返回数组中指定下标的值
     * @description: 获取数组中指定的下标的值
    */
    public T get(int index){
        // 判断下标是否越界
        isIndexValid(index);
        return (T) data[index];
    }

    /***
     * @author: kx
     * @date: 2025/3/26 19:44
     * @param index : 指定下标
     * @param value : 指定值
     * @description: 设置指定位置的值
    */
    public void set(int index, T value){
        // 判断value是否为空
        if (value == null){
            throw new NullPointerException("数据不能为空...");
        }
        // 判断下标是否越界
        isIndexValid(index);
        // 把指定下标的值设置为value
        data[index] = value;
    }

    /***
     * @author: kx
     * @date: 2025/3/26 19:49
     * @return boolean : 返回集合是否为空
     * @description: 判断集合是否为空
    */
    public boolean isEmpty(){
        return size == 0;
    }

    @Override
    public String toString() {
        return "MyArrayList{" +
                "data=" + Arrays.toString(data) +
                ", size=" + size +
                '}';
    }


    /***
     * @author: kx
     * @date: 2025/3/27 14:59
     * @param index : 指定下标
     * @description: 判断下标是否越界
    */
    public void isIndexValid(int index){
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("索引越界...");
        }
    }
}
